package com.kai.admin.config;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.kai.common.util.IpAddressUtil;
import com.kai.common.util.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 请求切面
 */
@Slf4j
@Aspect
@Component
public class RequestInfoAspect {

    @Around("execution(* com.kai.admin.controller..*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = WebUtil.getRequest();
        String url = request.getRequestURI();
        String ip = IpAddressUtil.get(request);

        Object result;

        Object[] args = joinPoint.getArgs();
        //接口参数过滤HttpServletRequest 和 HttpServletResponse 和 MultipartFile
        List<Object> requestList = Lists.newArrayList(args).stream()
                .filter(arg -> !(arg instanceof HttpServletRequest
                        || arg instanceof HttpServletResponse
                        || arg instanceof MultipartFile))
                .collect(Collectors.toList());
        long start = System.currentTimeMillis();
        try {
            result = joinPoint.proceed();
        } catch (Exception e) {
            long end = System.currentTimeMillis();
            //防止日志过长无法阅读
            String requestJsonStr = JSON.toJSONString(requestList);
            requestJsonStr = requestJsonStr.length() > 2000 ? requestJsonStr.substring(0, 2000) + "..." : requestJsonStr;
            log.info(" 处理请求 | IP:{} | url:{} | 耗时: {}ms | method:{} | args:{} | 返回异常:"
                    , ip
                    , url
                    , end - start
                    , request.getMethod()
                    , requestJsonStr
            );
            throw e;
        }
        long end = System.currentTimeMillis();
        //防止日志过长无法阅读
        String requestJsonStr = JSON.toJSONString(requestList);
        String responseJsonStr = JSON.toJSONString(result);
        requestJsonStr = requestJsonStr.length() > 2000 ? requestJsonStr.substring(0, 2000) + "..." : requestJsonStr;
        responseJsonStr = responseJsonStr.length() > 2000 ? responseJsonStr.substring(0, 2000) + "..." : responseJsonStr;
        log.info(" 处理请求 | IP:{} | url:{} | 耗时: {}ms | method:{} | args:{} | 返回:{}",
                ip,
                url,
                end - start,
                request.getMethod(),
                requestJsonStr,
                responseJsonStr
        );

        return result;
    }

}